using System.Linq;
using Exiled.API.Features;
using MEC;
using PlayerRoles;
using PlayerStatsSystem;
using RgCore.Events;
using RgCore.Misc;

namespace RgCore.GameModes
{
    public static class Normal_Score
    {
        public static void SetEnabled(bool enable)
        {
            if (enable)
            {
                Exiled.Events.Handlers.Player.Died += Player_Died;
                Exiled.Events.Handlers.Server.RespawningTeam += Server_RespawningTeam;
                Exiled.Events.Handlers.Scp049.FinishingRecall += Scp049_FinishingRecall;
                Exiled.Events.Handlers.Scp079.GainingExperience += Scp079_GainingExperience;
                Exiled.Events.Handlers.Warhead.Starting += Warhead_Starting;
                Exiled.Events.Handlers.Player.EnteringPocketDimension += Player_EnteringPocketDimension;
                EventProcessor.DamageResulting.Subscribe(Player_Hurting);
                Exiled.Events.Handlers.Player.ChangingRole += Player_ChangingRole;
            }
            else
            {
                Exiled.Events.Handlers.Player.Died -= Player_Died;
                Exiled.Events.Handlers.Server.RespawningTeam -= Server_RespawningTeam;
                Exiled.Events.Handlers.Scp049.FinishingRecall -= Scp049_FinishingRecall;
                Exiled.Events.Handlers.Scp079.GainingExperience -= Scp079_GainingExperience;
                Exiled.Events.Handlers.Warhead.Starting -= Warhead_Starting;
                Exiled.Events.Handlers.Player.EnteringPocketDimension -= Player_EnteringPocketDimension;
                EventProcessor.DamageResulting.Unsubscribe(Player_Hurting);
                Exiled.Events.Handlers.Player.ChangingRole -= Player_ChangingRole;
            }
        }

        private static void Player_ChangingRole(Exiled.Events.EventArgs.Player.ChangingRoleEventArgs ev)
        {
            if (ev.Reason == Exiled.API.Enums.SpawnReason.Escaped)
            {
                var team = ev.NewRole.GetTeam();
                if (RgCore.instance.Config.InspirationMode)
                {
                    foreach (var player in Player.List.Where(x => x.Role.Team == team && x.Zone == Exiled.API.Enums.ZoneType.Surface && x != ev.Player))
                    {
                        player.AddScore(500, "掩护玩家逃离设施");
                    }
                }
                ev.Player.AddScore(1800, "逃出设施");
            }
        }

        private static void Player_EnteringPocketDimension(Exiled.Events.EventArgs.Player.EnteringPocketDimensionEventArgs ev)
        {
            Timing.CallDelayed(0.5f, delegate ()
                                     {
                                         if (ev.IsAllowed)
                                             ev.Scp106.AddScore(200, "收入口袋");
                                     });
        }

        private static void Warhead_Starting(Exiled.Events.EventArgs.Warhead.StartingEventArgs ev)
        {
            ev.Player.AddScore(100, "启动核弹");
        }

        private static void Player_Hurting(DamageResultingEventArgs ev)
        {
            if ((ev.DamageHandler is FirearmDamageHandler || ev.DamageHandler is ExplosionDamageHandler) && ev.Player.IsScp)
            {
                ev.Attacker?.AddScoreSlight((int)(ev.DamageHandler as AttackerDamageHandler).Damage);
            }
        }

        private static void Scp079_GainingExperience(Exiled.Events.EventArgs.Scp079.GainingExperienceEventArgs ev)
        {
            if (ev.GainType != PlayerRoles.PlayableScps.Scp079.Scp079HudTranslation.ExpGainAdminCommand)
                ev.Player.AddScore(ev.Amount * 2, "获得经验");
        }

        private static void Scp049_FinishingRecall(Exiled.Events.EventArgs.Scp049.FinishingRecallEventArgs ev)
        {
            ev.Player.AddScore(100, "复活僵尸");
        }

        private static void Server_RespawningTeam(Exiled.Events.EventArgs.Server.RespawningTeamEventArgs ev)
        {
            foreach (Player player in Player.List.Where(x => x.IsAlive))
                player.AddScoreSlight(100);
        }

        private static void Player_Died(Exiled.Events.EventArgs.Player.DiedEventArgs ev)
        {
            if (Round.IsStarted)
                ScoreMvpHandler.KeepAlive.Remove(ev.Player);
            if (ev.DamageHandler.Base is UniversalDamageHandler udh && !Round.IsEnded)
            {
                DeathTranslation[] ava = new DeathTranslation[]
                {
                    DeathTranslations.Crushed, DeathTranslations.Falldown, DeathTranslations.SeveredHands
                };
                if (ava.Any(x => x.Id == udh.TranslationId))
                {
                    ev.Player.AddScore(-100, "意外死亡");
                }
            }
            if (ev.DamageHandler.Base is AttackerDamageHandler adh)
            {
                if (ev.Attacker.IsScp)
                {
                    switch (ev.TargetOldRole.GetTeam())
                    {
                        case Team.ClassD: ev.Attacker.AddScore(100, "杀死D级人员"); break;
                        case Team.Scientists: ev.Attacker.AddScore(150, "杀死科学家"); break;
                        case Team.FoundationForces: ev.Attacker.AddScore(200, "杀死MTF"); break;
                        case Team.ChaosInsurgency: ev.Attacker.AddScore(50, "杀死CI"); break;
                    }
                }
                else
                {
                    if (ev.TargetOldRole.IsHuman())
                    {
                        if (ev.DamageHandler.Base is FirearmDamageHandler fdh && fdh.Hitbox == HitboxType.Headshot)
                        {
                            int score = ev.TargetOldRole.GetTeam() == Team.ClassD || ev.TargetOldRole.GetTeam() == Team.Scientists ? 80 : 180;
                            ev.Attacker.AddScore(score, "<color=#FF0000>🎯爆头</color>击杀敌方");
                        }
                        else
                        {
                            int score = ev.TargetOldRole.GetTeam() == Team.ClassD || ev.TargetOldRole.GetTeam() == Team.Scientists ? 50 : 150;
                            ev.Attacker.AddScore(score, "击杀敌方");
                        }
                    }
                    else if (ev.TargetOldRole != RoleTypeId.Scp0492)
                    {
                        bool scp = ev.TargetOldRole != RoleTypeId.Scp0492;
                        ev.Attacker.AddScore(scp ? 2000 : 300, "击杀SCP");
                    }
                }
            }
        }
    }
}